package org.mspring.mlog.service.impl;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.mspring.mlog.entity.Attachment;
import org.mspring.mlog.service.AttachmentService;
import org.mspring.mlog.service.StorageService;
import org.mspring.mlog.service.exception.StorageException;
import org.mspring.mlog.utils.AttachmentUtils;
import org.mspring.platform.dao.hibernate.GenericDao;
import org.mspring.platform.utils.ImageUtils;
import org.mspring.platform.utils.Size;
import org.mspring.security.SecurityUtils;
import org.mspring.security.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

/**
 * 
 * @author Gao Youbo
 * @since 2013-06-18 16:34:42
 */
@Service
@Transactional
public class AttachmentServiceImpl extends GenericDao<Attachment, java.lang.Long> implements AttachmentService {

    @Autowired
    private StorageService storageService;

    @Override
    public Attachment createAttachment(MultipartFile mf, String from) throws StorageException, IOException {
        // TODO Auto-generated method stub
        return createAttachment(mf, from, null);
    }

    @Override
    public Attachment createAttachment(MultipartFile mf, String from, Long fid) throws StorageException, IOException {
        // TODO Auto-generated method stub
        User user = SecurityUtils.getCurrentUser();
        if (user == null) {
            log.warn("can't upload attachment, please login.");
            return null;
        }
        String url = storageService.put(AttachmentUtils.getUploadPath(mf), mf.getInputStream());

        Attachment attachment = new Attachment();
        attachment.setPath(url);
        attachment.setSize(mf.getSize());
        attachment.setUploadTime(new Date());
        attachment.setUser(user.getId());
        attachment.setFrom(from);
        attachment.setFid(fid);

        // 判断是否为图片
        String ext = FilenameUtils.getExtension(mf.getOriginalFilename());
        if (ImageUtils.isImage(ext)) {
            attachment.setIsImage(true);
            try {
                Size size = ImageUtils.getImageSize(mf.getInputStream());
                attachment.setImageWidth(size.getWidth());
                attachment.setImageHeight(size.getHeight());
            } catch (IOException e) {
                // TODO Auto-generated catch block
            }
        }
        return save(attachment);
    }

    @Override
    public Attachment createAttachment(InputStream is, String extension, Long user, String from, Long fid) throws IOException, StorageException {
        // TODO Auto-generated method stub
        String filename = AttachmentUtils.getUploadPath(extension);
        String src = storageService.put(filename, is);

        File file = storageService.get(src);
        Attachment attachment = new Attachment();
        attachment.setPath(src);
        attachment.setSize(FileUtils.sizeOf(file));
        attachment.setUploadTime(new Date());
        attachment.setUser(user);
        attachment.setFid(fid);
        attachment.setFrom(from);

        // 判断是否为图片
        if (ImageUtils.isImage(extension)) {
            attachment.setIsImage(true);
            Size size = ImageUtils.getImageSize(file);
            attachment.setImageWidth(size.getWidth());
            attachment.setImageHeight(size.getHeight());
        }
        return save(attachment);
    }

    @Override
    public List<Attachment> findAttachmentsByPost(Long post) {
        // TODO Auto-generated method stub
        return findAttachmentsByFid(post, Attachment.AttachFrom.FROM_POST);
    }

    @Override
    public List<Attachment> findAttachmentsByTwitter(Long twitter) {
        // TODO Auto-generated method stub
        return findAttachmentsByFid(twitter, Attachment.AttachFrom.FROM_TWITTER);
    }

    @Override
    public List<Attachment> findAttachmentsByFid(Long fid, String from) {
        // TODO Auto-generated method stub
        return list("select a from Attachment a where a.from = ? and a.fid = ?", from, fid);
    }

    @Override
    public void deleteAttachment(Long id) {
        // TODO Auto-generated method stub
        Attachment attachment = get(id);
        storageService.remove(attachment.getPath());
        super.remove(id);
    }

    @Override
    public void setAttachmentFid(Long id, String from, Long fid) {
        // TODO Auto-generated method stub
        Attachment attachment = get(id);
        if (attachment == null) {
            return;
        }
        attachment.setFid(fid);
        attachment.setFrom(from);
        update(attachment);
    }

    @Override
    public void deleteAttachment(Long fid, String from) {
        // TODO Auto-generated method stub
        List<Attachment> attachments = findAttachmentsByFid(fid, from);
        if (attachments != null && attachments.size() > 0) {
            for (Attachment attach : attachments) {
                storageService.remove(attach.getPath());
            }
        }
        executeUpdate("delete Attachment attach where attach.fid = ? and attach.from = ?", fid, from);
    }

}
